package interfaces.tips;

import java.util.List;

import org.fenggui.event.ButtonPressedEvent;
import org.fenggui.event.IButtonPressedListener;

import interfaces.hud.BasicHUD;
import interfaces.spawnMenu.SelectWindow;
import interfaces.spawnMenu.costumize.CustomizeWindow;
import interfaces.spawnMenu.costumize.hunters.HunterButton;
import interfaces.spawnMenu.costumize.hunters.HunterSelectContent;
import interfaces.spawnMenu.costumize.weapons.WeaponSelectContent;
import interfaces.spawnMenu.costumize.weapons.WeaponTableButton;
import interfaces.superWidgets.HorizontalScrollContent;

import settings.Config;

import fileHandling.ProfileHandler;
import fileHandling.language.interfaces.Tips;
import gameStates.absGamesStates.gui.AbsHUDState;
import gameStates.absGamesStates.gui.AbsSpawnState;
import gameStates.gui.GUIState;

import logic.common.player.Player;
import logic.common.player.playerListeners.HunterChangedEvent;
import logic.common.player.playerListeners.KillAssistEvent;
import logic.common.player.playerListeners.KillEvent;
import logic.common.player.playerListeners.MissionAssistEvent;
import logic.common.player.playerListeners.PlayerListener;
import logic.common.player.playerListeners.RespawnEvent;
import logic.common.player.playerListeners.TargetChangedEvent;
import logic.ships.equipmentListener.EquipmentListener;
import logic.ships.equipmentListener.ItemChangedEvent;
import logic.ships.equipmentListener.WeaponChangedEvent;
import main.InitGame;
import main.listeners.listenerClasses.GameListener;
import main.listeners.listenerClasses.gui.ChatActivatedEvent;
import main.listeners.listenerClasses.gui.ConsoleToggleEvent;
import main.listeners.listenerClasses.gui.GUIListener;
import main.listeners.listenerClasses.gui.IngameChangedEvent;
import main.listeners.listenerClasses.gui.ScoreBoardToggleEvent;
import main.listeners.listenerClasses.gui.SpawnMenuChangedEvent;

public class TipsManager {
	
	private static TipsManager manager;
	
	private Player player;
	
	private AbsHUDState hudState;
	
	private AbsSpawnState spawnState;
	private CustomizeWindow cw;
	
	private TipWindow currentWindow;
	private GUIState guiState;
	
	private TipsManager() {
		InitGame.get().addGameListener(new GameListener() {
			@Override
			public void gameStarted() {
				showSelectHunterWindow();
			}
			
			@Override
			public void gameFinished() {}
			@Override
			public void gameDestroyed() {}
		});
	}
	
	public static TipsManager get() { return manager; }
	
	public static void init() { manager = new TipsManager(); }
	
	public static boolean isInit() { return manager != null; }
	
	public void setupPlayer(Player player, AbsSpawnState spawnState, AbsHUDState hudState) {
		this.player = player;
		this.spawnState = spawnState;
		this.hudState = hudState;
		
		cw = spawnState.getSpawnMenu().getCustomWindow();
		
		addPlayerListener();
		
		Config.get().disableTips();
		ProfileHandler.changeSettings(Config.get());
	}
	
	private void addPlayerListener() {
		player.addPlayerListener(new PlayerListener() {
			@Override
			public void hunterChanged(HunterChangedEvent event) {
				showWeaponTabWindow();
				player.removePlayerListener(this);
			}
			
			@Override
			public void targetChanged(TargetChangedEvent event) {}
			@Override
			public void respawned(RespawnEvent event) {}
			@Override
			public void missionAssist(MissionAssistEvent event) {}
			@Override
			public void killed(KillEvent event) {}
			@Override
			public void killAssist(KillAssistEvent event) {}
		});
	}
	
	private void removeCurrentWindow() {
		if(guiState != null && currentWindow != null) guiState.removeWidget(currentWindow);
	}
	
	private void setCurrentWindow(GUIState guiState, TipWindow window) {
		removeCurrentWindow();
		currentWindow = window;
		this.guiState = guiState;
		guiState.addWidget(window);
	}
	
	public boolean selectHunterWindowOpen() {
		if(!(currentWindow instanceof TipLangWindow)) return false;
		TipLangWindow tlw = (TipLangWindow)currentWindow;
		return tlw.getTip() == Tips.Select_Hunter_Tip;
	}
	
	public boolean selectWeaponWindowOpen() {
		if(!(currentWindow instanceof TipLangWindow)) return false;
		TipLangWindow tlw = (TipLangWindow)currentWindow;
		return tlw.getTip() == Tips.Select_Weapon_Tip;
	}
	
	private void showSelectHunterWindow() {
		HunterSelectContent hsc = cw.getHunterSelectContent();
		HorizontalScrollContent<HunterButton> scrollContent = hsc.getHunterScrollContent();
		
		int width = cw.getWidth();
		int height = cw.getY();
		int x = cw.getX();
		int y = cw.getY() + scrollContent.getY() - height;
		
		TipLangWindow window = new TipLangWindow(width, height, Tips.Select_Hunter_Tip);
		window.setXY(x, y);
		
		setCurrentWindow(spawnState, window);
		
		IButtonPressedListener listener = new IButtonPressedListener() {
			@Override
			public void buttonPressed(ButtonPressedEvent e) {
				if(selectHunterWindowOpen()) showBuyHunterWindow();
			}
		};
		
		for(HunterButton b : scrollContent.getElements()) {
			b.addButtonListener(listener);
		}
	}
	
	private void showBuyHunterWindow() {
		int halfCWWidth = cw.getWidth() / 2;
		int x = cw.getX() + halfCWWidth;
		int y = 0;
		int width = halfCWWidth;
		int height = cw.getY();
		
		TipLangWindow window = new TipLangWindow(width, height, Tips.Buy_Hunter_Tip);
		window.setXY(x, y);
		
		setCurrentWindow(spawnState, window);
	}
	
	private void showWeaponTabWindow() {
		int width = cw.getWidth();
		int height = spawnState.getHeight() - cw.getY() - cw.getHeight();
		int x = cw.getX();
		int y = cw.getY() + cw.getHeight();
		
		final TipLangWindow window = new TipLangWindow(width, height, Tips.Weapon_Tab_Tip);
		window.setXY(x, y);
		
		setCurrentWindow(spawnState, window);
		
		cw.addWeaponSwitchTipListener(new IButtonPressedListener() {
			@Override
			public void buttonPressed(ButtonPressedEvent e) {
				if(currentWindow == window) {
					removeCurrentWindow();
					showSelectWeaponWindow();
				}
			}
		});
	}
	
	private void showSelectWeaponWindow() {
		int width = cw.getWidth();
		int height = spawnState.getHeight() - cw.getY() - cw.getHeight();
		int x = cw.getX();
		int y = cw.getY() + cw.getHeight();
		
		final TipLangWindow window = new TipLangWindow(width, height, Tips.Select_Weapon_Tip);
		window.setXY(x, y);
		
		setCurrentWindow(spawnState, window);
		
		IButtonPressedListener listener = new IButtonPressedListener() {
			@Override
			public void buttonPressed(ButtonPressedEvent e) {
				if(currentWindow == window) showBuytWeaponWindow();
			}
		};
		
		WeaponSelectContent wsc = cw.getWeaponSelectContent();
		List<WeaponTableButton> buttons = wsc.getAvailableWeaponButtons();
		for(WeaponTableButton b : buttons) {
			b.addButtonPressedListener(listener);
		}
	}
	
	private void showBuytWeaponWindow() {
		int width = cw.getWidth();
		int height = spawnState.getHeight() - cw.getY() - cw.getHeight();
		int x = cw.getX();
		int y = cw.getY() + cw.getHeight();
		
		final TipLangWindow window = new TipLangWindow(width, height, Tips.Buy_Weapon_Tip);
		window.setXY(x, y);
		
		setCurrentWindow(spawnState, window);
		
		player.getHunter().addEquipmentListener(new EquipmentListener() {
			@Override
			public void weaponAdded(WeaponChangedEvent event) {
				if(currentWindow == window) {
					showReadyWindow();
					player.getHunter().removeEquipmentListener(this);
				}
			}
			
			@Override
			public void weaponRemoved(WeaponChangedEvent event) {}
			@Override
			public void itemUsed(ItemChangedEvent event) {}
			@Override
			public void itemRemoved(ItemChangedEvent event) {}
			@Override
			public void itemAdded(ItemChangedEvent event) {}
		});
	}
	
	private void showReadyWindow() {
		SelectWindow sw = spawnState.getSpawnMenu().getSelectWindow();
		int width = sw.getWidth() * 2;
		int height = sw.getY();
		int x = spawnState.getWidth() - width;
		int y = 0;
		
		final TipLangWindow window = new TipLangWindow(width, height, Tips.Ready_Tip);
		window.setXY(x, y);
		
		setCurrentWindow(spawnState, window);
		
		InitGame.get().addGUIListener(new GUIListener() {
			@Override
			public void spawnMenuChanged(SpawnMenuChangedEvent event) {
				if(currentWindow == window) {
					showDefaultKeyWindow();
					InitGame.get().removeGUIListener(this);
				}
			}
			
			@Override
			public void scoreBoardToggled(ScoreBoardToggleEvent event) {}
			@Override
			public void ingameChanged(IngameChangedEvent event) {}
			@Override
			public void consoleToggled(ConsoleToggleEvent event) {}
			@Override
			public void chatActivated(ChatActivatedEvent event) {}
		});
	}
	
	private void showDefaultKeyWindow() {
		BasicHUD hud = hudState.getCurrentHUD();
		
		int width = hudState.getWidth() / 5;
		int x = hudState.getWidth() - width;
		int y = hud.getWindowHeight();
		int height = hud.getGameTimeWindow().getY() - y;
		
		DefaultKeyTipWindow window = new DefaultKeyTipWindow(width, height);
		window.setXY(x, y);
		
		setCurrentWindow(hudState, window);
	}
}